---
title: Theme Customization
order: 3
subGroup: advanced
---

# Theme customization

> This is an advanced guide about how to make a theme by yourself. If there are already themes that meet your needs(e.g. [the official theme](/official-theme)), you don't need to read this guide now!

Vite-pages itself doesn't render any concrete DOM node. Users can customize **anything** with a theme. That's why themes are so powerful.

To use a theme, users should export their theme from `_theme.tsx`. It should export a React component. It will be rendered by vite-pages core, and get useful info from props:

- All pages' static data
- All runtime data that is already loaded
- The current loading state of the app

Here is the interface of a theme:

<FileText src="../../packages/react-pages/theme.doc.d.ts" syntax="ts" />

You can learn more about the "data" received by the render functions in [the page data doc](/page-data).

This is probably [the simplest theme](https://github.com/vitejs/vite-plugin-react-pages/blob/main/packages/playground/basic/pages/_theme.tsx):

<FileText src="../../packages/playground/basic/pages/_theme.tsx" syntax="tsx" />

> Here is a more useful theme: [vite-pages-theme-doc](https://github.com/vitejs/vite-plugin-react-pages/blob/main/packages/theme-doc/src/index.tsx). Learn more about it in [this guide](/official-theme).

You can customize every bit of UI with a theme. Welcome to share your theme with a npm package!

## Suggestions

### To theme providers: make your theme easier to use

We encourage theme providers to export your theme as **a config function** that receives the user config and returns a `Theme`.

For example, the theme provider can export a theme like this:

```tsx
// The theme config function accepts navs config
export default function createTheme({ navs }: Option = {}): Theme {
  return ({ loadedData, loadState }) => {
    if (loadState.type !== 'loaded')
      return (
        <Layout navs={navs}>
          <p>Loading...</p>
        </Layout>
      )
    // Runtime page data for current page
    const pageData = loadedData[loadState.routePath]
    // the default export of the main module
    const Component = pageData.main.default
    return (
      <Layout navs={navs}>
        <Component />
      </Layout>
    )
  }
}
```

Theme consumers can use it to config their navs menu:

```tsx
// Theme users can configure sideMenu in `/_theme.tsx`:
import createTheme from 'theme-pkg'
export default createTheme({
  navs: [
    { path: '/guides/guide1', label: 'guide1' },
    { path: '/guides/guide2', label: 'guide1' },
  ],
})
```

As you can see, the theme is easier to use because **theme consumers don't need to know about the `Theme` API of vite-pages**. They only need to know about `createTheme` API from the theme. Users should be talking to the theme, instead of talking directly to vite-pages framework.

For this reason, we encourage theme providers to export a config function like the `createTheme` above.

> You can refer to [vite-pages-theme-doc](https://github.com/vitejs/vite-plugin-react-pages/blob/main/packages/theme-doc/src/index.tsx)

#### Release the power of Typescript

The above example shows another benefit for users: theme users can get Typescript type-check and intelliSense when they are configuring a theme. This is because users are calling the theme config function, instead of "exporting some configs".

## Share your theme!

It is easy to write a theme that is sharable and configurable.

If you have designed and implemented a theme (.e.g a blog theme, a document site theme), welcome to add a link to your theme package in this document!
